# -*- coding: utf-8 -*-
"""
   Copyright (C) 2011 Miguel de Dios

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   higher any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software Foundation,
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
"""

import os
import pygame
from pygame.locals import *
import sqlite3
from Util import *
from Frontend import *
from pprint import *

class ScreenSaver:
	last_time_screensaver = 0
	disable_screensaver = False
	list_default_images = []
	shuffle_list_default_images = []
	no_default_images = False
	black_screen = None
	image_last = None
	image_to_show = None
	id_rom = None
	
	
	def __init__(self, util_param = None, frontend_param = None):
		self.util = util_param
		self.frontend = frontend_param
		self.background = None
		
		self.list_default_images = os.listdir(self.util.options['dir_default_images_screensaver'])
		
		if (len(self.list_default_images) == 0):
			self.no_default_images = True
		
		#Create the black screen image
		self.black_screen = pygame.Surface((self.util.options["screen_width"], self.util.options["screen_height"]))
		self.black_screen.fill((0, 0, 0))
	
	
	def shuffle_images(self):
		if not self.shuffle_list_default_images:
			self.shuffle_list_default_images = self.list_default_images[:]
			random.shuffle(self.shuffle_list_default_images)
	
	def load_image(self):
		
		image_file_fullpath_str = None
		
		show_default_image = False
		if not self.no_default_images:
			if random.randint(0, 100) <= self.util.options['random_percent_default_images_screensaver']:
				show_default_image = True
		
		if not show_default_image:
			connection = sqlite3.connect(self.util.frontend_db)
			cursor = connection.cursor()
			
			count_attempts = 0
			id_rom = None
			while ((id_rom is None) and (self.id_rom == id_rom)) or (not image_file_fullpath_str) and (count_attempts < 10):
				cursor.execute("SELECT id, rom " + \
					"FROM roms " + \
					"WHERE disabled = 0 AND found = 1 " + \
					"ORDER BY random() LIMIT 1;")
				row = cursor.fetchall()[0]
				id_rom = row[0]
				rom_name = row[1]
				
				dir_rom = os.path.join(self.util.options["snapshots_directory"], rom_name)
				if os.path.exists(dir_rom):
					snaps = os.listdir(dir_rom)
					if (len(snaps) > 0):
						image_file_fullpath_str = os.path.join(dir_rom, snaps[0])
				
				count_attempts += 1
			
			
			if count_attempts == 10:
				#There is not a image from the rom screenshots.
				
				#Then try to load a default image
				if not self.no_default_images:
					show_default_image = True
			else:
				self.id_rom = id_rom
			
		if show_default_image:
			self.id_rom = None
			
			self.shuffle_images()
			
			default_image = self.shuffle_list_default_images.pop()
			
			if default_image:
				image_file_fullpath_str = os.path.join(self.util.options['dir_default_images_screensaver'], default_image)
				#print(image_file_fullpath_str)
		
		if image_file_fullpath_str:
			try:
				self.image_to_show = pygame.image.load(image_file_fullpath_str).convert()
			except pygame.error, message:
				#Can't load the image
				
				self.image_to_show = self.black_screen
			else:
				self.image_to_show = self.frontend.resize_to_screen(self.image_to_show)
		else:
			#Can't load the image
			
			self.image_to_show = self.black_screen
	
	def start(self):
		return self.start_second_step()
	
	
	def set_screensaver(self, enable = True):
		if enable:
			self.disable_screensaver = False
			self.last_time_screensaver = pygame.time.get_ticks()
		else:
			self.disable_screensaver = True
	
	
	def screen_saver_transition_normal(self):
		"""Blit the image centered on screen"""
		pos_y = (self.util.options["screen_height"] - self.image_to_show.get_height()) / 2
		pos_x = (self.util.options["screen_width"] - self.image_to_show.get_width()) / 2
		self.frontend.screen.fill((0, 0, 0))
		self.frontend.screen.blit(self.image_to_show, (pos_x, pos_y))
	
	
	def start_second_step(self):
		return_var = None
		
		if not self.disable_screensaver:
			#print(str(self.last_time_screensaver) + " + " + str(1000) + " * " + str(self.util.options['time_to_show_screensaver']) + " <= " + str(pygame.time.get_ticks()))
			if self.last_time_screensaver + 1000 * self.util.options['time_to_show_screensaver'] <= pygame.time.get_ticks():
				return_var = self.run_screen_saver()
		
		return return_var
	
	
	def run_screen_saver(self):
		return_var = False
		last_image = None
		
		time_last_image = pygame.time.get_ticks()
		
		connection = sqlite3.connect(self.util.frontend_db)
		cursor = connection.cursor()
		
		exit_var = False
		
		change_the_image = True
		time_transition_image = 0
		while not exit_var:
			
			if ((pygame.time.get_ticks() - time_last_image - time_transition_image) / 1000) > self.util.options['seconds_wait_between_screensaver_images']:
				time_last_image = pygame.time.get_ticks()
				change_the_image = True
			
			if change_the_image:
				self.load_image()
				
				time_transition_image = pygame.time.get_ticks()
				
				#Show the image
				if self.util.options['transational_effect_screensaver'] == 0:
					self.screen_saver_transition_normal()
				else:
					self.effects()
				
				self.image_last = self.image_to_show
				
				change_the_image = False
				time_transition_image = pygame.time.get_ticks() - time_transition_image
			
			ekey = self.frontend.get_events()
			
			if ekey == K_RETURN:
				return_var = self.id_rom
				if not self.util.options['can_played_game_show_in_screensaver']:
					return_var = None
			elif ekey != 0:
				#Exit of the screensaver
				break
			
			self.frontend.waitFrame()
			pygame.display.update()
		
		self.set_screensaver(False)
		
		return return_var
	
	
	def effects(self):
		effect = random.randint(1, 2)
		
		if effect == 1:
			self.effect_sunblind(vertical = True)
		elif effect == 2:
			self.effect_sunblind(vertical = False, horizontal = True)
	
	
	def effect_sunblind(self, vertical = True, horizontal = False):
		
		#There is not a last image, first execution
		if not self.image_last:
			self.screen_saver_transition_normal()
			return
		
		screen_new = self.frontend.screen.copy()
		screen_new.fill((0, 0, 0))
		pos_y = (self.util.options["screen_height"] - self.image_to_show .get_height()) / 2
		pos_x = (self.util.options["screen_width"] - self.image_to_show .get_width()) / 2
		screen_new.blit(self.image_to_show , (pos_x, pos_y))
		
		
		how_count_lines_change = 200#self.util.options["screen_height"] / 2
		
		while how_count_lines_change > 0:
			screen_last = self.frontend.screen.copy()
			screen_last.fill((0, 0, 0))
			pos_y = (self.util.options["screen_height"] - self.image_last.get_height()) / 2
			pos_x = (self.util.options["screen_width"] - self.image_last.get_width()) / 2
			screen_last.blit(self.image_last, (pos_x, pos_y))
			
			ar_screen_last = pygame.PixelArray (screen_last)
			ar_screen_new = pygame.PixelArray (screen_new)
			
			if vertical:
				for y in range(0, self.util.options["screen_height"], how_count_lines_change):
				#for y in range(0, self.util.options["screen_height"], 50):#, how_count_lines_change):
					for x in range(0, self.util.options["screen_width"]):
						try:
							ar_screen_last[x][y] = ar_screen_new[x][y]
						except IndexError:
							continue
			elif horizontal:
				for x in range(0, self.util.options["screen_width"], how_count_lines_change):
				#for y in range(0, self.util.options["screen_height"], 50):#, how_count_lines_change):
					for y in range(0, self.util.options["screen_height"]):
						try:
							ar_screen_last[x][y] = ar_screen_new[x][y]
						except IndexError:
							continue
			
			del ar_screen_last
			del ar_screen_new
			
			how_count_lines_change -= 1
			
			self.frontend.screen.blit(screen_last, (0, 0))
			
			self.frontend.waitFrame()
			pygame.display.update()